package com.soulkun.smarthome.ui.main.home.viewmodel

import androidx.databinding.ObservableArrayList
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.soulkun.smarthome.logic.dto.*
import com.soulkun.smarthome.logic.model.DeviceModel
import com.soulkun.smarthome.logic.repository.ApiRepository
import com.soulkun.smarthome.logic.vo.DeviceCommandHistoryVO
import com.soulkun.smarthome.logic.vo.DeviceDataHistoryItemVO
import com.soulkun.smarthome.logic.vo.DeviceDataHistoryVO
import com.soulkun.smarthome.logic.vo.DeviceVO
import soulkun.library.mvvm.adapter.clearAndAddAll
import soulkun.library.utils.toast

class AppMainHomeDeviceViewModel : ViewModel() {

    val deviceLiveData = MutableLiveData<DeviceVO>()

    val deviceDataRecentList = ObservableArrayList<DeviceDataDTO>()
    val deviceDataHistoryList = ObservableArrayList<DeviceDataHistoryVO>()
    val deviceCommandHistory = DeviceCommandHistoryVO(null, ObservableArrayList())

    val typeTitleList = arrayListOf<String>("最近", "历史")
    val historyTitleList = arrayListOf<String>("数据", "指令")

    fun modifyDeviceName(deviceName: String, onFinishListener: () -> Unit) =
        ApiRepository.modifyDeviceName(
            this,
            DeviceModel(
                id = deviceLiveData.value!!.id,
                name = deviceName,
                familyId = deviceLiveData.value!!.familyId
            )
        ) {
            it.statusMessage.toast()
            deviceLiveData.value!!.name.set(deviceName)
            onFinishListener()
        }

    fun deleteDevice() = ApiRepository.deleteDevice(
        DeviceModel(
            id = deviceLiveData.value!!.id,
            familyId = deviceLiveData.value!!.familyId
        )
    )

    fun getDeviceRecentData() = ApiRepository.getDeviceData(
        this,
        DeviceModel(
            id = deviceLiveData.value!!.id,
            productId = deviceLiveData.value!!.productId,
            familyId = deviceLiveData.value!!.familyId
        )
    ) {
        deviceDataRecentList.clearAndAddAll(it.data)
    }

    fun getDeviceAttributeList(onComplete: () -> Unit) = ApiRepository.getDeviceAttributeList(
        this,
        DeviceModel(
            id = deviceLiveData.value!!.id,
            productId = deviceLiveData.value!!.productId,
            familyId = deviceLiveData.value!!.familyId
        )
    ) {
        val list = it.data.map { attributeModel ->
            DeviceDataHistoryVO(
                attributeModel.id,
                ObservableArrayList(),
                attributeModel.name,
                attributeModel.description,
                attributeModel.unit,
                attributeModel.unitSymbol
            )
        }
        deviceDataHistoryList.clearAndAddAll(list)
        onComplete()
    }

    fun getDeviceCommandList() = ApiRepository.getDeviceCommandList(
        DeviceModel(
            id = deviceLiveData.value!!.id,
            productId = deviceLiveData.value!!.productId,
            familyId = deviceLiveData.value!!.familyId
        )
    )

    fun postDeviceCommand(commandId: Long, qos: Int, timeout: Int) =
        ApiRepository.postDeviceCommand(
            DeviceCommandPostDTO(
                deviceLiveData.value!!.familyId,
                deviceLiveData.value!!.id,
                deviceLiveData.value!!.productId,
                commandId,
                qos,
                timeout
            )
        )

    fun getDeviceDataHistory(deviceDataHistoryVO: DeviceDataHistoryVO) {
        ApiRepository.getDeviceDataHistory(
            this,
            DeviceDataHistoryRequestDTO(
                deviceLiveData.value!!.familyId,
                deviceLiveData.value!!.id,
                deviceLiveData.value!!.productId,
                arrayListOf(deviceDataHistoryVO.id),
                "2017-01-01T00:00:00",
                null,
                30,
                "DESC",
                deviceDataHistoryVO.cursor
            )
        ) {
            val deviceDataStreamDTO =
                it.data.datastreams.find { deviceDataStreamDTO -> deviceDataStreamDTO.id == deviceDataHistoryVO.id }
            deviceDataHistoryVO.dataHistoryList.addAll(
                deviceDataStreamDTO?.datapoints?.map { deviceDataPointDTO ->
                    DeviceDataHistoryItemVO(
                        deviceDataPointDTO.at,
                        deviceDataPointDTO.value,
                        deviceDataStreamDTO.unit,
                        deviceDataStreamDTO.unitSymbol
                    )
                } ?: ArrayList<DeviceDataHistoryItemVO>()
            )
            deviceDataHistoryVO.cursor = it.data.cursor
        }
    }

    fun getDeviceCommandHistory(onFinishListener: () -> Unit) =
        ApiRepository.getDeviceCommandHistory(
            this,
            DeviceCommandHistoryRequestDTO(
                deviceLiveData.value!!.familyId,
                deviceLiveData.value!!.id,
                deviceLiveData.value!!.productId,
                null,
                null,
                10,
                deviceCommandHistory.cursor
            )
        ) {
            deviceCommandHistory.cursor = it.data.cursor
            deviceCommandHistory.commandHistoryList.addAll(it.data.items)
            onFinishListener()
        }

}